<?php
/**
 * WB_ObjStore class
 * Derived classes implementation pattern:
 * SAVE method:
 * 	- if OBJ already exists => replace with new modification timestamp + expiration timestamp
 *  - if OBJ ! exists => save with modification + expiration timestamps
 * RESTORE method:
 * 	- if OBJ exists in store => is it expired ?
 * 								a) NO  => return it
 * 								b) YES => is there a newer version ?
 * 											c) NO  => return 'stale' object with 'expired' status
 * 											d) YES => return newer version
 * 
 * @author Jean-Lou Dupont
 * @version @@package-version@@
 */
//{{include
require_once 'web-bloks/BaseClass/BaseClass.php';
//include}}
 abstract class WB_ObjStore 
 	extends WB_BaseClass
 {
 	/**
 	 * Locality flag
 	 */
 	var $_isLocal = null;
	
 	/**
 	 * Constructor
 	 */
	public function __construct( $params = null )
	{
		parent::__construct( $params );
	}
	
	/**
	 * Returns 'true' if the store is local 
	 *  i.e. on the same machine.
	 * Must be initialized by derived classes.
	 * 
	 * @return boolean
	 */	
	public function isLocal()
	{
		return $this->_isLocal;
	}

	// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	// ERROR codes
	// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%	
	const CREATION_SUCCESS = 0;
	const CREATION_FAILURE = 1;
	const CREATION_FAILURE_EXISTS = 2;
	const CREATION_FAILURE_COMMUNICATION = 3;
	const CREATION_FAILURE_RACE = 4;

	 // ======================================================
	 // Abstract Interface 
	 // ======================================================
	/**
	 * Initialization phase.
	 * This method is necessary for some classes
	 * of storage where initialization can not be
	 * done in the __constructor because exceptions
	 * might be throwned.
	 */
	abstract public function init();
		
	/**
	 * Saves the specified object in the store.
	 * Must be implemented in derived classes.
	 * 
	 * @throw ObjStore_Exception or derived
	 * @param $identifier Object of Identifier Class
	 * @param $obj Object of WB_CacheableObjectClass or derived
	 * @return boolean
	 */	
	abstract public function save( $identifier, &$obj );
	
	/**
	 * Restores an object through the specified key.
	 * Must be implemented in derived classes.
	 * 
	 * @throw ObjStore_Exception or derived	  
	 * @param $identifier Object of Identifier Class
	 * @return $obj of WB_CacheableObjectClass or derived herein
	 */	
	abstract public function restore( $identifier );
	
	/**
	 * Deletes an object specified by $identifier.
	 * Must be implemented in derived classes.
	 * 
	 * @throw ObjStore_Exception or derived
	 * @param $identifier Object of Identifier class
	 * @return boolean true if at least 1 object 
	 *   identified through $identifier was deleted.
	 */	
	abstract public function delete( $identifier );

	/**
	 * Creates an element.
	 * Must be implemented in derived classes.
	 * The algorithm for creation should be around the following:
	 * 1) Try to RESTORE object with identifier $identifier
	 *    1a) IF successful, then return step 4
	 *    1b) IF communication failure, then CREATION_FAILURE_COMMUNICATION
	 *    1c) IF communication is OK and RESTORE OK then step 2
	 *    
	 * 2) SAVE object with DISPOSABLE = YES and short EXPIRATION 
	 *      + creation_state = in_progress, expiration short
	 *      + unique ID
	 *      
	 *    2a) IF successful, then step 3
	 *    2b) IF failure of communication, then CREATION_FAILURE_COMMUNICATION
	 *    2c) IF failure (other), then CREATION_FAILURE
	 *    
	 * 3) RESTORE object with identifier $identifier
	 *    3a) IF successful, then step 5
	 *    3b) IF failure of communication, then CREATION_FAILURE_COMMUNICATION
	 *    3c) IF failure (other), then CREATION_FAILURE
	 * 
	 * 4) RESTORE was successful but need to check creation state 
	 *    4a) IF creation_state == in_progress && !expired
	 *          then CREATION_FAILURE  
	 *            (somebody else is progressing a creation with $identifier)
	 *    4b) IF creation_state == in_progress && expired
	 *          then step 2
	 *            (somebody tried to create but some failure occured)
	 *    4c) other, then CREATION_FAILURE
	 * 
	 * 5) SAVED & RESTORED ok but need to make sure it is really ours
	 *    We need to claim the object really fast before it expires!
	 *    5a) UID is same as expected, then step 6
	 *    5b) UID is different, then CREATION_FAILURE_RACE
	 * 
	 * 6) CLEAR creation progress state and SAVE object;
	 *    Only then can we really claim to have created the object
	 *    6a) IF save successful, then CREATION_SUCCESS
	 *    6b) IF save failure, then 
	 * 
	 * @return $code boolean
	 * @param $identifier WB_Identifier
	 * @param $obj WB_CacheableObjectClass or derived from
	 */
	abstract public function create( $identifier, &$obj );
	
 } // end class
